package com.fy.fyspace.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fy.fyspace.common.auth.StpKit;
import com.fy.fyspace.common.auth.authenum.SpaceUserRoleEnum;
import com.fy.fyspace.common.auth.model.SpaceUser;
import com.fy.fyspace.common.auth.model.SpaceUserPermission;
import com.fy.fyspace.common.auth.model.SpaceUserRole;
import com.fy.fyspace.common.result.R;
import com.fy.fyspace.constant.KeysConstant;
import com.fy.fyspace.constant.ResultMessageConstant;
import com.fy.fyspace.ex.ConditionException;
import com.fy.fyspace.mapper.*;
import com.fy.fyspace.model.entity.Space;
import com.fy.fyspace.model.entity.User;
import com.fy.fyspace.model.enums.space.SpaceTypeEnum;
import com.fy.fyspace.model.enums.spaceuser.SpaceUserStatusEnum;
import com.fy.fyspace.model.vo.space.SpaceDetailVO;
import com.fy.fyspace.model.vo.spaceuser.TeamSpaceVO;
import com.fy.fyspace.model.vo.user.UserSessionVO;
import com.fy.fyspace.service.SpaceUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.fy.fyspace.common.result.R.no;
import static com.fy.fyspace.common.result.R.ok;

/**
 * @author fwq
 * @description 针对表【spaceuser(空间用户表)】的数据库操作Service实现
 * @createDate 2025-02-01 23:53:40
 */
@Slf4j
@Service
public class SpaceUserServiceImpl extends ServiceImpl<SpaceUserMapper, SpaceUser> implements SpaceUserService {

    @Autowired
    private SpaceUserMapper spaceUserMapper;

    @Autowired
    private SpaceUserRoleMapper spaceUserRoleMapper;

    @Autowired
    private SpaceUserPermissionMapper spaceUserPermissionMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SpaceMapper spaceMapper;

    /**
     * 空间用户登录
     *
     * @param userId 用户ID
     * @return 登录结果
     */
    @Override
    public R login(Long userId) {

        LambdaQueryWrapper<SpaceUser> wp = new LambdaQueryWrapper<>();
        wp.eq(SpaceUser::getUserId, userId)
                .eq(SpaceUser::getIsDelete, SpaceUserStatusEnum.NOT_DELETE.getStatus());
        List<SpaceUser> spaceUserList = spaceUserMapper.selectList(wp);

        //如果为空表示用户还没创建自己的团队空间或加入团队空间，不用获取角色信息放入缓存
        if (spaceUserList.isEmpty()) {
            if (StpKit.SPACE.isLogin()) {
                clearUserAuthInfo(userId);
                StpKit.SPACE.logout();
            }

            // 登录用户（只使用SPACE登录系统）
            StpKit.SPACE.login(userId);
            ok();

        }else {
            for (SpaceUser spaceUser : spaceUserList) {
                Long userRoleId = spaceUser.getUserRoleId();

                try {
                    // 清除旧的登录信息（如果有）
                    if (StpKit.SPACE.isLogin()) {
                        clearUserAuthInfo(userId);
                        StpKit.SPACE.logout();
                    }

                    LambdaQueryWrapper<SpaceUserRole> wp1 = new LambdaQueryWrapper<>();
                    wp1.eq(SpaceUserRole::getId, userRoleId)
                            .eq(SpaceUserRole::getIsDelete, SpaceUserStatusEnum.NOT_DELETE.getStatus());
                    SpaceUserRole spaceUserRole = spaceUserRoleMapper.selectOne(wp1);

                    Long spaceId= spaceUser.getSpaceId();

                    // 登录用户（只使用SPACE登录系统）
                    StpKit.SPACE.login(userId);

                    // 存储角色和权限信息到Redis
                    String roleKey = KeysConstant.SPACE_ROLE_REDIS_KEY + userId;
                    String permKey = KeysConstant.SPACE_PERMISSION_REDIS_KEY + userId;

                    // 存储角色信息到Redis
                    String roleInfo = JSON.toJSONString(spaceUserRole);
                    redisTemplate.opsForValue().set(roleKey, roleInfo);

                    // 存储权限信息到Redis
                    List<Long> permissionIds = spaceUserRole.getSpaceUserPermissionIds();
                    if (permissionIds != null && !permissionIds.isEmpty()) {
                        List<SpaceUserPermission> permissions = spaceUserPermissionMapper.selectBatchIds(permissionIds);
                        String permInfo = JSON.toJSONString(permissions);
                        redisTemplate.opsForValue().set(permKey, permInfo);
                    }

                    log.info("用户{}登录成功，角色和权限信息已存入Redis", userId);
                    return ok();

                } catch (Exception e) {
                    log.error("登录过程发生错误", e);
                    return no("登录失败：" + e.getMessage());
                }
            }
        }
        return ok();
    }

    /**
     * 获取团队空间信息
     *
     * @param userId 用户ID
     * @return 团队空间信息列表
     */
    @Override
    public R getTeamSpaceInfo(Long userId) {
        try {
            // 查询用户所有的空间关联信息
            LambdaQueryWrapper<SpaceUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SpaceUser::getUserId, userId)
                    .eq(SpaceUser::getIsDelete, SpaceUserStatusEnum.NOT_DELETE.getStatus());
            List<SpaceUser> spaceUsers = spaceUserMapper.selectList(wrapper);

            // 如果用户还未创建或加入团队，返回空集合
            if (spaceUsers.isEmpty()) {
                return ok(new ArrayList<>());
            }

            // 存储结果的集合
            List<TeamSpaceVO> teamSpaceVOList = new ArrayList<>();

            // 遍历用户的所有空间关联信息
            for (SpaceUser spaceUser : spaceUsers) {
                // 根据空间ID查询空间详细信息
                Space space = spaceMapper.selectById(spaceUser.getSpaceId());
                if (space != null && space.getSpaceType().equals(SpaceTypeEnum.TEAM.getSpaceType())) {
                    TeamSpaceVO teamSpaceVO = new TeamSpaceVO();
                    // 设置基本信息
                    teamSpaceVO.setSpaceId(space.getId());
                    teamSpaceVO.setUserId(userId);
                    teamSpaceVO.setSpaceName(space.getSpaceName());
                    teamSpaceVO.setCreateUserId(spaceUser.getCreateUserId());
                    teamSpaceVO.setNickName(spaceUser.getNickName());
                    teamSpaceVO.setSpaceLevel(space.getSpaceLevel());
                    teamSpaceVO.setMaxSize(space.getMaxSize());
                    teamSpaceVO.setMaxCount(space.getMaxCount());
                    teamSpaceVO.setTotalSize(space.getTotalSize());
                    teamSpaceVO.setTotalCount(space.getTotalCount());
                    teamSpaceVO.setCreateTime(space.getCreateTime());
                    teamSpaceVO.setSpaceType(space.getSpaceType());
                    // 设置是否是创建者
                    teamSpaceVO.setIsCreator(userId.equals(spaceUser.getCreateUserId()));

                    teamSpaceVOList.add(teamSpaceVO);
                }
            }

            log.info("用户{}成功获取团队空间信息，共{}个空间", userId, teamSpaceVOList.size());
            return ok(teamSpaceVOList);

        } catch (Exception e) {
            log.error("获取用户{}的团队空间信息时发生错误", userId, e);
            return no(ResultMessageConstant.SYSTEM_ERROR);
        }
    }

    /**
     * 清除用户的权限和角色缓存
     *
     * @param userId 用户ID
     */
    private void clearUserAuthInfo(Long userId) {
        try {
            // 清除角色缓存 - 使用同样的key直接删除整个set
            String roleKey = KeysConstant.SPACE_ROLE_REDIS_KEY + userId;
            redisTemplate.delete(roleKey);

            // 清除权限缓存 - 使用同样的key直接删除整个set
            String permKey = KeysConstant.SPACE_PERMISSION_REDIS_KEY + userId;
            redisTemplate.delete(permKey);

            log.debug("已清除用户{}的角色缓存key: {}，权限缓存key: {}", userId, roleKey, permKey);
        } catch (Exception e) {
            log.error("清除用户{}的权限缓存时发生错误", userId, e);
        }
    }

    /**
     * 创建团队空间
     *
     * @param userSessionVO
     * @return
     */
    @Override
    public R createTeamSpace(UserSessionVO userSessionVO) {
        Long userId = userSessionVO.getId();
        try {
            // 1. 检查用户是否已创建团队空间
            LambdaQueryWrapper<SpaceUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SpaceUser::getCreateUserId, userId)
                    .eq(SpaceUser::getUserId, userId);
            List<SpaceUser> existingSpaces = spaceUserMapper.selectList(wrapper);

            // 如果有团队空间记录
            if (!existingSpaces.isEmpty()) {
                // 检查是否被禁用
                if (existingSpaces.get(0).getIsDelete().equals(SpaceUserStatusEnum.IS_DELETE.getStatus())) {
                    return no("您的团队空间已被禁用，请联系开发者");
                }
                // 如果未被禁用
                return no("每个用户只能创建一个团队空间");
            }

            // 2. 检查用户加入的团队数量
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SpaceUser::getUserId, userId)
                    .eq(SpaceUser::getIsDelete, SpaceUserStatusEnum.NOT_DELETE.getStatus())
                    .ne(SpaceUser::getCreateUserId, userId); // 排除自己创建的
            long joinedCount = spaceUserMapper.selectCount(wrapper);
            if (joinedCount >= 3) {
                return no("您最多只能加入3个团队空间");
            }

            // 3. 创建团队空间
            Space space = new Space();
            space.setSpaceName(userSessionVO.getUserName() + "的团队空间"); // 使用用户名作为默认空间名
            space.setSpaceLevel(0L); // 默认为普通版
            space.setMaxSize(1024L * 1024L * 100L); // 默认100MB
            space.setMaxCount(100L); // 默认100张图片
            space.setTotalSize(0L);
            space.setTotalCount(0L);
            space.setUserId(userId);
            space.setSpaceType(SpaceTypeEnum.TEAM.getSpaceType());
            space.setIsDelete(SpaceUserStatusEnum.NOT_DELETE.getStatus());
            spaceMapper.insert(space);

            // 4. 创建空间用户关联
            SpaceUser spaceUser = new SpaceUser();
            spaceUser.setUserId(userId);
            spaceUser.setSpaceId(space.getId());
            spaceUser.setNickName(userSessionVO.getUserName()); // 使用用户名作为昵称
            spaceUser.setCreateUserId(userId);
            spaceUser.setUserRoleId(SpaceUserRoleEnum.SPACE_OWNER.getRoleId()); // 默认角色ID，应该是管理员角色
            spaceUser.setIsDelete(SpaceUserStatusEnum.NOT_DELETE.getStatus());
            spaceUserMapper.insert(spaceUser);

            log.info("用户{}成功创建团队空间，空间ID：{}", userId, space.getId());
            return ok("创建团队空间成功");

        } catch (Exception e) {
            log.error("用户{}创建团队空间时发生错误", userId, e);
            return no(ResultMessageConstant.SYSTEM_ERROR);
        }
    }

    /**
     * 加入团队空间
     *
     * @param spaceId       空间ID
     * @param userSessionVO 用户会话信息
     * @return 加入结果
     */
    @Override
    public R joinTeamSpace(Long spaceId, UserSessionVO userSessionVO) {
        Long userId = userSessionVO.getId();
        try {
            // 1. 检查空间是否存在且是团队空间
            Space space = spaceMapper.selectById(spaceId);
            if (space == null || !space.getSpaceType().equals(SpaceTypeEnum.TEAM.getSpaceType())) {
                return no("该团队空间不存在");
            }

            // 2. 检查用户是否已经在这个空间中
            LambdaQueryWrapper<SpaceUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SpaceUser::getUserId, userId)
                    .eq(SpaceUser::getSpaceId, spaceId);
            SpaceUser existingMember = spaceUserMapper.selectOne(wrapper);

            if (existingMember != null) {
                if (existingMember.getIsDelete().equals(SpaceUserStatusEnum.IS_DELETE.getStatus())) {
                    return no("您已被移出该团队空间");
                }
                return no("您已经是该团队空间的成员");
            }

            // 3. 检查用户加入的团队数量（不包括自己创建的）
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SpaceUser::getUserId, userId)
                    .eq(SpaceUser::getIsDelete, SpaceUserStatusEnum.NOT_DELETE.getStatus())
                    .ne(SpaceUser::getCreateUserId, userId);
            long joinedCount = spaceUserMapper.selectCount(wrapper);
            if (joinedCount >= 3) {
                return no("您最多只能加入3个团队空间");
            }

            // 4. 创建空间用户关联
            SpaceUser spaceUser = new SpaceUser();
            spaceUser.setUserId(userId);
            spaceUser.setSpaceId(spaceId);
            spaceUser.setNickName(userSessionVO.getUserName()); // 使用用户名作为默认昵称
            spaceUser.setCreateUserId(space.getUserId()); // 设置空间创建者ID
            spaceUser.setUserRoleId(SpaceUserRoleEnum.SPACE_MEMBER.getRoleId()); // 设置为普通成员角色
            spaceUser.setIsDelete(SpaceUserStatusEnum.NOT_DELETE.getStatus());
            spaceUserMapper.insert(spaceUser);

            log.info("用户{}成功加入团队空间，空间ID：{}", userId, spaceId);
            return ok("成功加入团队空间");

        } catch (Exception e) {
            log.error("用户{}加入团队空间{}时发生错误", userId, spaceId, e);
            return no(ResultMessageConstant.SYSTEM_ERROR);
        }
    }

    @Autowired
    private UserMapper userMapper;

    @Override
    public SpaceDetailVO getSpaceDetail(Long spaceId, Long userId) {
        // 1. 获取空间基本信息
        log.info("获取空间详情，spaceId: {}, userId: {}", spaceId, userId);
        Space space = spaceMapper.selectById(spaceId);
        if (space == null || !space.getSpaceType().equals(SpaceTypeEnum.TEAM.getSpaceType())) {
            throw new ConditionException("空间不存在或不是团队空间");
        }
        log.info("空间基本信息: {}", space);

        SpaceDetailVO detailVO = new SpaceDetailVO();
        
        // 2. 设置基本信息
        detailVO.setSpaceId(space.getId());
        detailVO.setSpaceName(space.getSpaceName());
        detailVO.setSpaceLevel(space.getSpaceLevel());
        detailVO.setCreateTime(space.getCreateTime());
        detailVO.setUpdateTime(space.getUpdateTime());
        detailVO.setCreateUserId(space.getUserId());
        
        // 3. 设置空间容量信息
        detailVO.setTotalSize(space.getTotalSize());
        detailVO.setMaxSize(space.getMaxSize());
        double usagePercent = space.getMaxSize() > 0 ? 
            (double) space.getTotalSize() / space.getMaxSize() * 100 : 0;
        detailVO.setUsagePercent(Math.round(usagePercent * 100.0) / 100.0); // 保留两位小数
        
        // 4. 查询成员统计
        LambdaQueryWrapper<SpaceUser> memberWrapper = new LambdaQueryWrapper<>();
        memberWrapper.eq(SpaceUser::getSpaceId, spaceId)
                .eq(SpaceUser::getIsDelete, SpaceUserStatusEnum.NOT_DELETE.getStatus());
        List<SpaceUser> allMembers = spaceUserMapper.selectList(memberWrapper);
        
        detailVO.setTotalMembers(allMembers.size());
        
        // 统计管理员和普通成员数量
        long adminCount = allMembers.stream()
                .filter(m -> SpaceUserRoleEnum.SPACE_ADMIN.getRoleId().equals(m.getUserRoleId()))
                .count();
        detailVO.setAdminCount((int) adminCount);
        detailVO.setNormalCount(allMembers.size() - (int) adminCount);
        
        // 5. 获取成员详细信息
        List<SpaceDetailVO.MemberInfo> memberInfos = allMembers.stream().map(member -> {
            SpaceDetailVO.MemberInfo info = new SpaceDetailVO.MemberInfo();
            info.setUserId(member.getUserId());
            
            // 获取用户基本信息
            User user = userMapper.selectById(member.getUserId());
            if (user != null) {
                info.setUserName(user.getUserName());
                info.setAvatar(user.getUserAvatar());
                info.setNickName(user.getUserName());
                // 如果是创建者,设置创建者用户名
                if (member.getUserId().equals(space.getUserId())) {
                    detailVO.setCreateUserName(user.getUserName());
                }
            }
            
            // 获取角色信息
            SpaceUserRole role = spaceUserRoleMapper.selectById(member.getUserRoleId());
            if (role != null) {
                info.setRoleName(role.getRoleName());
            }
            
            info.setJoinTime(member.getCreateTime());
            
            return info;
        }).collect(Collectors.toList());
        
        detailVO.setMembers(memberInfos);
        
        return detailVO;
    }
}
